package org.jeecg.modules.simulator.model.line.park;

import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.simulator.Simulator;
import org.jeecg.modules.simulator.SimulatorState;
import org.jeecg.modules.simulator.model.MetroTrain;
import org.jeecg.modules.simulator.model.line.park.equipment.ParkerBiz;
import org.jeecg.modules.simulator.model.line.park.equipment.ParkerPhysics;
import org.jeecg.modules.simulator.model.orbit.OrbitPath;
import org.jeecg.modules.simulator.model.orbit.OrbitPoint;
import org.jeecg.modules.simulator.model.train.TrainBiz;
import org.jeecg.modules.simulator.model.train.action.ActionRecordersStatus;
import org.jeecg.modules.simulator.model.train.event.ParkSendTrainEvent;

import org.jeecg.modules.simulator.model.line.station.station.Station;
import org.jeecg.modules.simulator.model.train.action.TrainActionRecorders;
import org.jeecg.modules.simulator.util.SpringUtil;
import lombok.Getter;
import lombok.Setter;

import java.time.LocalTime;
import java.util.*;

import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * 停车场、车辆段
 *
 * @program: 场段--业务对象：有上下行出站站点，未发车队列，将要发车队列，
 * 发车过程场段要做的工作：
 * 1、场段在初始化的时候，获取取对应发车的车站对象，
 * 2、trainManager提前两秒秒检查数据，看是否到了发车时间，如有发车则修改动作命令，同时通过消息发送要发车的record记录
 * 3、场段监控消息，获得消息后，把消息放在待处理消息中，
 * 4、每秒场段检查待处理消息
 * 5、根据待处理消息，拿到车辆id，给车辆分配车次号，同时找到对应发车站id，对应自己的上下行出站ID，获取站对象，
 * 6、给车装配轨道
 * 6、把分配的发车车辆从未上线队列取出，然后放入将要发车队列中
 * 下线业务：
 * 收到下线车辆消息，修改车辆状态，修改车辆位置，把车辆从将要发车队列中取出，放入未上线队列中
 * <p>
 * <p>
 * 位置描述：
 * @description:
 * @author: renzhg
 * @create: 2024-08-13 11:14
 **/
@Slf4j
public abstract class Parker implements Simulator {
    private static final Logger logger = LoggerFactory.getLogger(Parker.class);
    @Setter
    @Getter
    String name;
    @Setter
    @Getter
    String id;
    ParkerPhysics parkerPhysics = new ParkerPhysics();
    @Setter
    @Getter
    String lineId;

    @Setter
    @Getter
    Station upOut;
    @Setter
    @Getter
    Station downOut;
    @Setter
    @Getter
    long offset;
    @Setter
    @Getter
    boolean open;
    @Setter
    @Getter
    String parkType;
    @Setter
    @Getter
    boolean isup;

    @Getter
    OrbitPath workOrbitPath;

    Map<String, OrbitPoint> workOrbitPointMap = new HashMap<>();

    public void setWorkOrbitPath(OrbitPath orbitPath) {
        this.workOrbitPath = orbitPath;
        orbitPath.forEach(orbitPoint -> {
            workOrbitPointMap.put(orbitPoint.getOrbitName(), orbitPoint);
        });
    }

    public void setUpOutStationId(String upOut) {
        this.parkerPhysics.setUpOut(upOut);
    }

    public void setDownOutStationId(String downOut) {
        this.parkerPhysics.setDownOut(downOut);
    }

    public String getUpOutStationId() {
        return parkerPhysics.getUpOut();
    }

    public String getDownOutStationId() {
        return parkerPhysics.getDownOut();
    }


    ParkerBiz parkerBiz;

    //运营状态
    SimulatorState simulatorState;

    //没有上线的列车
    @Setter
    @Getter
    Map<String, MetroTrain> notOnlineTrainMap = new HashMap<>();
    @Setter
    @Getter
    Map<String, TrainActionRecorders> trainActionRecordersMap = new HashMap<>();


    public void trainAction() {

    }


    public void downLoadTran(MetroTrain train) {
//        MetroTrain train = (MetroTrain) event.getSource();
//        willStartTrainMap.remove(train.getTrainId() + "-" + train.getTrainNum());
//        train.setTrainNum("");
//        train.setTrainId("");
//        notOnlineTrainMap.put(train.getGroupId(), train);


    }


    /**
     * @param trainActionRecorders
     * @return void
     * @description: 1、检查是否有要发车的车辆
     * 2、如果有，从待发车车辆中取出一个车辆，给车辆分配ID和车次号
     * 3、修改车辆位置到发车车站，
     * 4、把分配的发车车辆从未上线队列取出，然后放入将要发车队列中
     * @date 2024/7/25 14:43
     **/
    public void saveTrainRecorder(TrainActionRecorders trainActionRecorders) {
        logger.debug(trainActionRecorders.getRocordersId());
        trainActionRecordersMap.put(trainActionRecorders.getRocordersId(), trainActionRecorders);

    }


    
    /**
     * @description: 从场段中拿出列车设置列车的运行方向，设置列车的状态为开始运行
     *
     * @author:  renzhg 
     * @date:  2024/9/18 15:12
     **/
    private void startTrain(TrainActionRecorders trainActionRecorders) {

        String key="";
        Iterator<Map.Entry<String, MetroTrain>> iterator = notOnlineTrainMap.entrySet().iterator();
        if (iterator.hasNext()) {
            Map.Entry<String, MetroTrain> entry = iterator.next();
            key=entry.getKey();
        }
        if(key.equals("")){
            return;
        }
        MetroTrain train = notOnlineTrainMap.get(key);
        train.setIsRuningUp(this.isup);//设立上下行方向
        trainActionRecorders.setStatus(ActionRecordersStatus.start);
        trainActionRecorders.moveNext();
        String idnume = trainActionRecorders.getRocordersId();
        train.setTrainId(idnume.split("-")[0]);
        train.setTrainNum(idnume.split("-")[1]);
        train.setBelongLineId(this.lineId);
        train.setTimeCounter(0L);
        TrainBiz trainBiz = new TrainBiz(workOrbitPointMap);
        train.setTrainBiz(trainBiz);
        SpringUtil.getApplicationContext().publishEvent(new ParkSendTrainEvent(train));

        notOnlineTrainMap.remove(key);

    }


    private void downTrain(MetroTrain train) {

    }


    /**
     * @description: 时刻表数据检查
     * 1、检查时刻表是否有要发车的车辆
     * 2、如果有，从待发车车辆中取出一个车辆，给车辆分配ID和车次号
     * 3、修改车辆位置到发车车站，
     * @author: renzhg
     * @date: 2024/7/25 14:43
     **/
//    Boolean checkTrainTimetable(LocalTime time) {
//        System.out.println("检查是否有开始运行的车辆");
////        Map<String, TrainActionRecorders> trainActionRecordersMap = trainActionRdsManager.getTrainActionRecordersMap();
//        Map<String, TrainActionRecorders> trainActionRecordersMap =  parkerBiz.getTrainActionRecordersMap();
//        for (String key : trainActionRecordersMap.keySet()) {
//            LocalTime firstActionTime = trainActionRecordersMap.get(key).getFistActionTime();
//            if (TimeUtil.compareLocalTimes(time, firstActionTime) == 0) {
//                System.out.println("到了开始时间");
//                if(notOnlineTrainMap.size()>0){
//                }
////                trainActionRecordersMap.get(key).setStatus(ActionRecordersStatus.start);
////                if (!trainActionRecordersMap.get(key).moveNext()) {
////                    return false;
////                }
//            }
//        }
//        return true;
//    }
    public boolean isInParkerStation(String stationid) {
        if (parkerPhysics.getUpOut().equals(stationid) || parkerPhysics.getDownOut().equals(stationid)) {
            return true;
        }
        return false;
    }

    /**
     * @description: 1、产生列车
     * 2、给没有分配列车的列车分配走行线路
     * @author: renzhg
     * @date: 2024/8/26 14:29
     **/

    public void init() {
        // 初始化停车场
    }

    @Override
    public LocalTime getCurrentTime() {
        return null;
    }

    @Override
    public void nextTime(String now, Integer step) {

        LocalTime nowTime = LocalTime.parse(now);
        List<String> startedTrainList=new ArrayList<>();

//        trainActionRecordersMap.forEach((k, v) -> {

            for (String key : trainActionRecordersMap.keySet()) {
                LocalTime firstActionTime = trainActionRecordersMap.get(key).getFistActionTime();

                LocalTime clonedTime = nowTime.withNano(nowTime.getNano());
                LocalTime updatedTime = clonedTime.minusSeconds(-1);
                if (firstActionTime != null && firstActionTime.equals(updatedTime)) {
                    startTrain(trainActionRecordersMap.get(key));
                    startedTrainList.add(key);
                }
            }
//        });
        startedTrainList.forEach(v->{
            trainActionRecordersMap.remove(v);
        });

        startedTrainList.clear();

    }
}
